unit Config;

interface

uses
  Config.Attribute;

type
  TAppConfig = class
  private
    fTrace: integer;
    fWWWPath: string;
    fLogPath: string;
  public
    [Default('c:\www\')]
    property WWWPath: string read fWWWPath write fWWWPath;
    [Default('c:\logs\')]
    property LogPath: string read fLogPath write fLogPath;
    [Default(3)]
    property Trace: integer read fTrace write fTrace;
  end;

  TUserConfig = class

  end;

  TConfig = class
  private
    class var fApp: TAppConfig;
    class var fUser: TUserConfig;
    class constructor Create;
    class destructor Destroy;

    class function NewApp(const s: string): TAppConfig;
    class function NewUser(const s: string): TUserConfig;

    class procedure SaveApp(const aFilename: string);
    class procedure SaveUser(const aFilename: string);

    class function getAppPath : string;
    class function getUserPath : string;
  public
    class property Application: TAppConfig read fApp;
    class property User: TUserConfig read fUser;
  end;

implementation

uses
  SysUtils, IOUtils, Helper.Serialization, Helper.SpecialFolder, uFileVersionInfo;

{ TConfig }

class constructor TConfig.Create;
var
  User, app: string;
  fnApp, fnUser : string;
begin
  fnApp := getAppPath + 'config.json';
  fnUser := getUserPath + 'config.json';

  if TFile.Exists(fnApp) then
    app := TFile.ReadAllText(fnApp)
  else
    app := '{}';

  if TFile.Exists(fnUser) then
    User := TFile.ReadAllText(fnUser)
  else
    User := '{}';

  fApp := NewApp(app);
  fUser := NewUser(User);
end;

class destructor TConfig.Destroy;
begin
  SaveApp(getAppPath+'config.json');
  SaveUser(getUserPath+'config.json');
  fApp.Free;
  fUser.Free;
end;

class function TConfig.getAppPath: string;
var
  fvi: TFileVersionInfo;
begin
  fvi := TFileVersion.getVersionInfo;
  if fvi.CompanyName = '' then
    fvi.CompanyName := 'Company';
  if fvi.ProductName = '' then
    fvi.ProductName := 'Product';
  result := TSpecialFolder.CommonAppData + '\' + fvi.CompanyName + '\' + fvi.ProductName + '\';
end;

class function TConfig.getUserPath: string;
var
  fvi: TFileVersionInfo;
begin
  fvi := TFileVersion.getVersionInfo;
  if fvi.CompanyName = '' then
    fvi.CompanyName := 'Company';
  if fvi.ProductName = '' then
    fvi.ProductName := 'Product';
  result := TSpecialFolder.UserAppData + '\' + fvi.CompanyName + '\' + fvi.ProductName + '\';
end;

class function TConfig.NewApp(const s: string): TAppConfig;
begin
  result := TAppConfig.Create;
  result.deserialize(s);
end;

class function TConfig.NewUser(const s: string): TUserConfig;
begin
  result := TUserConfig.Create;
  result.deserialize(s);
end;

class procedure TConfig.SaveApp(const aFilename: string);
var
  s: string;
  path : string;
begin
  s := fApp.serialize;
  path := getAppPath;
  TDirectory.CreateDirectory(path);
  TFile.WriteAllText(path +'config.json', s);
end;

class procedure TConfig.SaveUser(const aFilename: string);
var
  s: string;
  path : string;
begin
  s := fUser.serialize;
  path := getUserPath;
  TDirectory.CreateDirectory(path);
  TFile.WriteAllText(path+'config.json', s);
end;

end.
